package com.nets.packet;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import io.netty.channel.Channel;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author sig
 * @since 2016/9/17
 */
public abstract class AbstractPacket implements PacketI {
    private PacketTypeI packetType;
    private JSONObject object;
    private Channel channel;

    public AbstractPacket() {
        object = new JSONObject(true);
    }

    @Override
    public int getType() {
        return null == packetType ? 0 : packetType.getType();
    }

    @Override
    public JSONObject getObject() {
        return object;
    }

    public void setObject(JSONObject object) {
        this.object = object;
    }

    public PacketTypeI getPacketType() {
        return packetType;
    }

    public void setPacketType(PacketTypeI packetType) {
        this.packetType = packetType;
    }

    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }

    public void put(String key, Object value) {
        object.put(key, value);
    }

    public void put(String key, Object value,
                    SimplePropertyPreFilter filter) {
        String jsonString = JSON.toJSONString(value, filter);

        if (value instanceof List<?>) {
            List<?> list = JSON.parseObject(jsonString, List.class);
            object.put(key, list);
        } else if (value.getClass().isArray()) {
            Object[] objects = JSON.parseObject(jsonString, Object[].class);
            object.put(key, objects);
        } else {
            Object obj = JSON.parseObject(jsonString, Object.class);
            object.put(key, obj);
        }
    }

    public void putAll(Map<? extends String, ?> map) {
        object.putAll(map);
    }

    public byte getByte(String key) {
        return object.getByteValue(key);
    }

    public short getShort(String key) {
        return object.getShortValue(key);
    }

    public int getInt(String key) {
        return object.getIntValue(key);
    }

    public long getLong(String key) {
        return object.getLongValue(key);
    }

    public float getFloat(String key) {
        return object.getFloatValue(key);
    }

    public double getDouble(String key) {
        return object.getDoubleValue(key);
    }

    public String getString(String key) {
        return object.getString(key);
    }

    public <T> List<T> getBeanList(String key, Class<T> clazz) {
        List<T> list = new LinkedList<>();
        JSONArray jsonArray = object.getJSONArray(key);

        if (null != jsonArray) {

            for (Object tmp : jsonArray) {

                if (null == tmp) continue;
                JSONObject obj = (JSONObject) tmp;
                list.add(JSON.toJavaObject(obj, clazz));
            }
        }
        return list;
    }

    public JSONArray getJsonArray(String key) {
        return (JSONArray) object.get(key);
    }

    public <T> T getBean(Class<T> clazz) {
        return JSON.toJavaObject(object, clazz);
    }

    public <T> T getBean(String key, Class<T> clazz) {
        JSONObject obj = (JSONObject) object.get(key);
        return JSON.toJavaObject(obj, clazz);
    }

    public <T> T getBean(String key, Class<T> clazz, List<String> list) {
        String jsonStr = JSON.toJSONString(object.get(key)).trim();

        for (String tmp : list) {

            if (null == tmp) continue;
            StringBuilder target = new StringBuilder();
            target.append("\"").append(tmp).append("\"").append(":{}");
            StringBuilder replacement = new StringBuilder();
            replacement.append("\"").append(tmp).append("\"").append(":[]");
            jsonStr = jsonStr.replace(target, replacement);
        }
        return JSON.parseObject(jsonStr, clazz);
    }

    public boolean has(String key) {
        return object.get(key) != null;
    }
}
